#-*- coding:utf-8 -*-
'''
Created on Oct 18, 2012

@author: johnny
'''
import Queue, math
import test_db

GET_TIMEOUT = 2

class JobRuntimeError(Exception):
    def __init__(self, msg):
        self.msg = msg
        
    def __str__(self):
        return Exception.__str__(self) + self.msg

class Runner(object):
    def __init__(self, job_queue, results_queue, job_count):
        self.job_queue = job_queue
        self.results_queue = results_queue
        self.db = test_db.TestDB()
        self.total = job_count
        self.current = 0
    
    def update_result(self, jb):
        results = (jb.uid, jb.test_name, jb.start_time,
                   jb.end_time, jb.results, jb.output)
        results = self.parse_result(results)
        self.db.insert('results', results)
    
    def update_current(self, uid, status):
        condition = "where uid='%s'" % str(uid)
        self.db.update_column('status', status, 'current_tests', condition)
    
    def get_status(self, uid):
        keyword = "where uid='%s'" % str(uid)
        status = self.db.query('current_tests', keyword, 'status')
        status = [list(x) for x in status]
        if len(status):
            return status[0][0]
        
    
    def parse_result(self, result):
        rst_dict = {}
        uid, name, s_time, e_time, rst_obj, log_path = result
        rst_dict['uid'] = uid
        rst_dict['name'] = name
        rst_dict['start_time'] = s_time
        rst_dict['end_time'] = e_time
        rst_dict['log_path'] = log_path
        
        if "SKIPPED" == rst_obj:
            rst_dict['result'] = "SKIPPED"
            rst_dict['error_instance'] = ""
            rst_dict['traceback'] = ""
        
        elif not rst_obj:
            rst_dict['result'] = "FAILED"
            rst_dict['error_instance'] = ""
            rst_dict['traceback'] = ""
        
        elif not rst_obj.wasSuccessful():
            rst_dict['result'] = "FAILED"
            error_instance = rst_obj.errors[0][0]
            traceback = rst_obj.errors[0][1]
            rst_dict['error_instance'] = str(error_instance)
            rst_dict['traceback'] = traceback
        else:
            rst_dict['result'] = 'PASSED'
            rst_dict['error_instance'] = ''
            rst_dict['traceback'] = ''
        
        return rst_dict
    
    def set_progress(self, status='RUNNING', prg=None):
        if not prg:
            percentage = math.floor(float(self.current) / float(self.total) * 100)
            percentage = str(int(percentage)) + '%'   
        else: 
            percentage = prg
        self.db.update_progress(status, percentage)
        
    def run(self, resultdir):
                
        while True:
            try:
                jb = self.job_queue.get(timeout=GET_TIMEOUT)
            except Queue.Empty:
                self.set_progress("FINISHED")
                break
            else:
                jb.set_base_result_dir(resultdir)
                jb.logging.start_logging()
                if self.get_status(jb.uid) != "SKIPPED":
                    self.update_current(jb.uid, "TESTING")
                
                try:
                    if self.get_status(jb.uid) != "SKIPPED":
                        jb.run()
                    else:
                        jb.skip()
                except Exception, e:
                    self.set_progress('FINISHED')
                    self.update_current(jb.uid, "DONE")
                    raise
                else:
                    self.current += 1
                    self.set_progress()
                    self.update_result(jb)
                    if self.get_status(jb.uid) != "SKIPPED":
                        self.update_current(jb.uid, "DONE")
                                
                #self.results_queue.put(results)
                self.results_queue.put(jb)
            
            